package com.dataextend.service;

import com.alibaba.fastjson.JSONArray;
import com.dataextend.entity.RequestRemainAnalysis;
import com.dataextend.mapper.master.ClickhouseMapper;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *  Clickhouse 测试
 */

@Service
public class ClickhouseRemainService {
    @Autowired
    ClickhouseMapper clickhouseMapper;

    /**
     * 除法计算
     */
    private static String chufa(long param1, long param2){
        DecimalFormat dF = new DecimalFormat("0.00000");
        if (param2 > 0L){
            return dF.format((float) param1/param2);
        } else {
            return "0";
        }

    }

    /**
     *  clickhouse查询
     */
    private JSONObject calculateRemain(String dataDate, Integer nDays, List<JSONObject> eventCodes, List<JSONObject> filterParameter){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> events = new ArrayList<>();
        JSONObject returnInfo = new JSONObject(true);
        List<JSONObject> everyDaySubs = new ArrayList<JSONObject>();
        JSONObject firstDay = new JSONObject(true);
        for (JSONObject obj : eventCodes){
            String event = obj.getString("eventCode");
            events.add(event);
        }

        int num = 0;
        int dataCount = 0;  // 记录第一天总人数
        for (int i=0; i< nDays; i++){

            try {
                long startDate = simpleDateFormat.parse(dataDate).getTime();
                long endDate = startDate + (24*60*60*1000) *(i);
                String nowDate = simpleDateFormat.format(new Date(endDate));

                if (num == 0) {
                    //  第一天
                    String str_1 = "select count(distinct distinct_id) from userprofile_analysis_model ";
                    String str_2 = "where datadate = '" + dataDate + "'" + " and clickevent ='" + events.get(0) + "'";
                    String str_first = null;
                    String condition = null;
                    StringBuilder permission = new StringBuilder();
                    // 过滤条件[设备属性/用户属性]
                    if (filterParameter.size()>0){
                        for (JSONObject obj : filterParameter){
                            String type = obj.getString("type");
                            String field = obj.getString("field");
                            String name = obj.getString("name");
                            String tag = obj.getString("tag");
                            if (type.equals("event")){
                                condition = " and (" + field + "='" + tag + "')";
                                permission.append(condition);

                            } else {
                                String fieldName = "tag_" + field;
                                condition = " and (" + fieldName + "='" + tag + "')";
                                permission.append(condition);
                            }
                        }
                        str_first = str_1 + str_2 + permission.toString();
                    } else {
                        str_first = str_1 + str_2;
                    }

                    System.out.println("---------str_first:" + str_first);
                    int firstDayNum = clickhouseMapper.firstDay(str_first);
                    dataCount = firstDayNum;
                    firstDay.put("date", dataDate);
                    firstDay.put("people", firstDayNum);
                    firstDay.put("percent", "100%");
                    everyDaySubs.add(firstDay);

                } else {
                    // 后续留存
                    String str_1 = "select count(distinct t2.distinct_id) from (select distinct_id  from userprofile_analysis_model ";
                    String str_2 = "where datadate= '" + dataDate + "'" + " and clickevent ='" + events.get(0) + "'";
                    String str_3 = ") t1";
                    String str_4 = " inner join (select distinct_id from ads.userprofile_analysis_model where datadate='" + nowDate + "'" + " and clickevent ='" + events.get(1) + "'";
                    String str_5 = ") t2 on t1.distinct_id = t2.distinct_id";
                    String str_after = null;
                    String condition = null;
                    StringBuilder permission = new StringBuilder();

                    if (filterParameter.size()>0){
                        for (JSONObject obj : filterParameter){
                            String type = obj.getString("type");
                            String field = obj.getString("field");
                            String name = obj.getString("name");
                            String tag = obj.getString("tag");
                            if (type.equals("event")){
                                condition = " and (" + field + "='" + tag + "')";
                                permission.append(condition);

                            } else {
                                String fieldName = "tag_" + field;
                                condition = " and (" + fieldName + "='" + tag + "')";
                                permission.append(condition);
                            }
                        }
                        str_after = str_1 + str_2 + permission.toString() + str_3 + str_4 + permission.toString() + str_5;
                    } else {
                        str_after = str_1 + str_2 + str_3 + str_4 + str_5;
                    }

                    System.out.println("---------str_after:" + str_after);
                    JSONObject afterDay = new JSONObject(true);
                    int afterDayNum = clickhouseMapper.afterDay(str_after);
                    String afterPercent = chufa(afterDayNum, dataCount);
                    DecimalFormat dec = new DecimalFormat("0.00");
                    afterDay.put("date", nowDate);
                    afterDay.put("people", afterDayNum);
                    afterDay.put("percent", Double.parseDouble(dec.format(Double.parseDouble(afterPercent)*100)) + "%");
                    everyDaySubs.add(afterDay);
                }

                num+=1;
            } catch (Exception e){
                e.printStackTrace();
            }
        }

        returnInfo.put("dateValue", dataDate);
        returnInfo.put("subs", everyDaySubs);
        return returnInfo;
    }


    /**
     *  留存分析 查询主函数
     */
    public JSONObject reaminAnalysis(RequestRemainAnalysis requestRemainAnalysis){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        JSONArray detailList = new JSONArray();
        List<String> dataList = new ArrayList<>();
        JSONObject returnObject = new JSONObject();
        try {
            long startDate = simpleDateFormat.parse(requestRemainAnalysis.getStartDate()).getTime();
            long endDate = simpleDateFormat.parse(requestRemainAnalysis.getEndDate()).getTime();
            // 近n日数据
            int nDays =(int) (endDate - startDate) / (24*60*60*1000) +1;
            System.out.println("近n日数据: " + nDays);
            int j = 0;
            for (long i=startDate; i<= endDate; i+=86400000){
                JSONObject dateDetail = new JSONObject();
                String dataDate = simpleDateFormat.format(new Date(i));
                dataList.add(dataDate);
                System.out.println("--------------dataDate:" + dataDate);
                dateDetail = calculateRemain(dataDate, nDays-j, requestRemainAnalysis.getEventCode(), requestRemainAnalysis.getFilterParameter());
                detailList.add(dateDetail);
                j+=1;

            }
            returnObject.put("dataList", dataList);
            returnObject.put("detailList", detailList);
            return returnObject;

        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }

}
